<template>
  <div class="custom-table-container" :style="{ maxWidth: maxWidth }">
    <table class="custom-table">
      <thead>
        <tr>
          <th
            v-for="(column, index) in columns"
            :key="index"
            :style="getHeaderCellStyle(column)"
          >
            {{ column.title }}
          </th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(row, rowIndex) in data" :key="rowIndex">
          <td
            v-for="(column, colIndex) in columns"
            :key="colIndex"
            :style="getBodyCellStyle(column)"
            :class="{ 'ellipsis': column.ellipsis !== false }"
            :title="column.ellipsis !== false ? getCellValue(row, column) : ''"
          >
            <slot
              :name="`column-${column.key}`"
              :row="row"
              :value="getCellValue(row, column)"
              :index="rowIndex"
            >
              {{ getCellValue(row, column) }}
            </slot>
          </td>
        </tr>
      </tbody>
    </table>
    <div v-if="data.length === 0" class="empty-table">
      {{ emptyText }}
    </div>
  </div>
</template>

<script setup>
import { computed } from 'vue';

const props = defineProps({
  // 表格列配置
  columns: {
    type: Array,
    required: true,
    validator: (value) => {
      return value.every(
        (column) => column.key !== undefined && column.title !== undefined
      );
    },
  },
  // 表格数据
  data: {
    type: Array,
    default: () => [],
  },
  // 表格最大宽度
  maxWidth: {
    type: String,
    default: '100%',
  },
  // 空数据时显示的文字
  emptyText: {
    type: String,
    default: '暂无数据',
  },
  // 默认对齐方式
  defaultAlign: {
    type: String,
    default: 'left',
    validator: (value) => ['left', 'center', 'right'].includes(value),
  },
  // 是否显示边框
  bordered: {
    type: Boolean,
    default: true,
  },
  // 是否显示斑马纹
  striped: {
    type: Boolean,
    default: false,
  },
  // 行悬停高亮
  hoverable: {
    type: Boolean,
    default: true,
  },
});

// 获取单元格值
const getCellValue = (row, column) => {
  if (column.formatter) {
    return column.formatter(row[column.key], row);
  }
  return row[column.key];
};

// 获取表头单元格样式
const getHeaderCellStyle = (column) => {
  return {
    textAlign: column.align || props.defaultAlign,
    width: column.width || 'auto',
    minWidth: column.minWidth || 'auto',
    maxWidth: column.maxWidth || 'none',
    ...(column.headerStyle || {}),
  };
};

// 获取表格单元格样式
const getBodyCellStyle = (column) => {
  return {
    textAlign: column.align || props.defaultAlign,
    width: column.width || 'auto',
    minWidth: column.minWidth || 'auto',
    maxWidth: column.maxWidth || 'none',
    ...(column.cellStyle || {}),
  };
};

// 计算表格类名
const tableClass = computed(() => ({
  'is-bordered': props.bordered,
  'is-striped': props.striped,
  'is-hoverable': props.hoverable,
}));
</script>

<style scoped>
.custom-table-container {
  overflow-x: auto;
  font-size: 14px;
}

.custom-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.custom-table.is-bordered th,
.custom-table.is-bordered td {
  border: 1px solid #ebeef5;
}

.custom-table th {
  background-color: #f5f7fa;
  color: #333;
  font-weight: 500;
  padding: 12px 10px;
}

.custom-table td {
  padding: 10px;
  color: #606266;
  border-bottom: 1px solid #ebeef5;
}

.custom-table.is-striped tbody tr:nth-child(even) {
  background-color: #fafafa;
}

.custom-table.is-hoverable tbody tr:hover {
  background-color: #f5f7fa;
}

.empty-table {
  text-align: center;
  padding: 20px;
  color: #909399;
}

.ellipsis {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
</style>